package gao.xioalei.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.google.gson.Gson;

import java.util.Map;

/**
 * Java web token 工具类
 *
 * @author qiaokun
 * @date 2018/08/10
 */
public class JwtUtil {
    /**
     * 过期时间一天，
     * TODO 正式运行时修改为15分钟
     */
    private static final long EXPIRE_TIME = 24 * 60 * 60 * 1000;
    /**
     * token私钥
     */
    private static final String TOKEN_SECRET = "f26e587c28064d0e855e72c0a6a0e618";

    /**
     * 校验token是否正确
     *
     * @param token 密钥
     * @return 是否正确
     */
    public static boolean verify(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm)
                    .build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public static String getUsername(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("loginName").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获取登陆用户ID
     * @param token
     * @return
     */
    public static String getUserId(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("userId").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获取版本号
     * @param token
     * @return
     */
    public static Integer getVersion(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("version").asInt();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获取角色
     * @param token
     * @return
     */
    public static String [] getRoles(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("roles").asArray(String.class);
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获取权限点
     * @param token
     * @return
     */
    public static String [] getAuth(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("auth").asArray(String.class);
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获取被暂时赋予的权限点权限点
     * @param token
     * @return
     */
    public static Map<String, String []> getTransientAuth(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            String json=jwt.getClaim("transientAuth").asString();
            if(json!=null)
                return new Gson().fromJson(json,Map.class);
            else
                return null;
        } catch (JWTDecodeException e) {
            return null;
        }
    }

//    /**
//     * 生成签名,15min后过期
//     *
//     * @param userId 用户id
//     * @param roles 用户角色
//     * @param auth 用户权限
//     * @param authResource 用户被赋予权限的资源
//     * @param version 版本号
//     * @return 加密的token
//     */
//    public static String sign(String userId, String[] roles,String [] auth,Map<String,String []> authResource,Integer version) {
//        //            过期时间
//        Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
////            私钥及加密算法
//        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
////            设置头部信息
//        Map<String, Object> header = new HashMap<>(2);
//        header.put("typ", "JWT");
//        header.put("alg", "HS256");
//        // 附带用户id、用户角色、用户权限、用户被赋予的权限对应的操作资源信息，生成签名
//        JWTCreator.Builder front=JWT.create()
//                .withHeader(header)
//                .withClaim("version",version)
//                .withClaim("userId",userId)
//                .withArrayClaim("roles",roles)
//                .withArrayClaim("auth",auth);
//        for (Map.Entry<String, String []> authRes:authResource.entrySet()) {
//            front.withArrayClaim(authRes.getKey(),authRes.getValue());
//        }
//        return front
//                .withExpiresAt(date)
//                .sign(algorithm);
//    }

}
